//
// Created by cmj on 2020/7/10.
//

#ifndef ERLUA_ERLUA_ERROR_H
#define ERLUA_ERLUA_ERROR_H

#include <stdexcept>
#include "erl_nif.h"
#include "lua.hpp"

constexpr int ERLUA_NOT_SUPPORT_SMP = 100001;       // 这个库必须在开启了SMP的程序中使用
constexpr unsigned int ERLUA_MAX_STR_LEN = 20480;    // 最大字符串长度
constexpr int ERLUA_DEFAULT_SIZE_HINT = 7;          // 默认列表大小
//static constexpr unsigned int ERLUA_MAX_TUPLE_LEN = 30;     // 最大TUPLE 字段个数

struct ERLUA_GLOBAL {
    ERL_NIF_TERM ok;
    ERL_NIF_TERM nil;
    ERL_NIF_TERM atom_true;
    ERL_NIF_TERM atom_false;
    ERL_NIF_TERM error;
    ERL_NIF_TERM exception;
    ERL_NIF_TERM wrong_args_nums;
    ERL_NIF_TERM not_lua_state;
    ERL_NIF_TERM allocation_fail;
    ERL_NIF_TERM runtime_error;
    ERL_NIF_TERM syntax_error;
    ERL_NIF_TERM gc_error;
    ERL_NIF_TERM msgh_error;
    ERL_NIF_TERM yield;
    ERL_NIF_TERM cannot_open;
    ERL_NIF_TERM unknown;
};

extern struct ERLUA_GLOBAL erlua_global;
extern void erlua_init_global(ErlNifEnv *caller_env);
extern ERL_NIF_TERM erlua_ecode(decltype(LUA_OK) ecode);
extern void erlua_dump_stack(lua_State *L, char const *file, int line);
#define ERLUA_STACK(state) erlua_dump_stack(state, __FILE__, __LINE__)

struct erlua_exception : std::runtime_error {
    explicit erlua_exception(const std::string &str) : std::runtime_error(str) {
        ex_term = erlua_global.unknown;
    }

    explicit erlua_exception(const std::string &str, ERL_NIF_TERM term) : std::runtime_error(str) {
        ex_term = term;
    }
    ERL_NIF_TERM ex_term;
};

#endif //ERLUA_ERLUA_ERROR_H
